package moxl.relaxng.model;

import java.util.LinkedList;
import java.util.List;

import moxl.dom.QualifiedName;
import moxl.dom.mutable.MutableElement;

public class PatternParentSupport extends PatternSupport
{
	private final List<Pattern> childPatterns = new LinkedList<Pattern>();

	protected PatternParentSupport(MutableElement backingElement)
	{
		super(backingElement);
	}

	/**
	 * Add a child patten onto the list of children held by this pattern. The hierarchy is doubly connected, both at this level and at the underlying DOM level.
	 */
	public void addPattern(Pattern pattern)
	{
		childPatterns.add(pattern);
		getElement().addChild(pattern.getElement());
	}

	public void assertWellDefined() throws SchemaNotWellDefinedException
	{
		if (childPatterns.isEmpty())
		{
			throw new SchemaNotWellDefinedException("No child patterns", this);
		}
		for (Pattern childPattern : childPatterns)
		{
			childPattern.assertWellDefined();
		}
	}

	public ElementPattern createElementPattern(QualifiedName name)
	{
		ElementPattern result = new ElementPattern(name);
		addPattern(result);
		return result;
	}

	public ElementPattern createElementPattern(String name)
	{
		ElementPattern result = new ElementPattern(name);
		addPattern(result);
		return result;
	}

	public EmptyElementPattern createEmptyElementPattern(QualifiedName name)
	{
		EmptyElementPattern result = new EmptyElementPattern(name);
		addPattern(result);
		return result;
	}

	public EmptyElementPattern createEmptyElementPattern(String name)
	{
		EmptyElementPattern result = new EmptyElementPattern(name);
		addPattern(result);
		return result;
	}

	public ChoicePattern createChoicePattern()
	{
		ChoicePattern result = new ChoicePattern();
		addPattern(result);
		return result;
	}

	public GroupPattern createGroupPattern()
	{
		GroupPattern result = new GroupPattern();
		addPattern(result);
		return result;
	}

	@Override
	public String toString()
	{
	    return getElement().getLocalName();
	}

}
